package nbcp.service

import nbcp.base.comm.Require
import nbcp.base.extend.*
import nbcp.base.utils.Md5Util
import java.lang.Exception

object WeiXinPayUtil {
    inline fun <reified T> check(wxModel: T, signFieldName: String = "sign"): String {
        var type = T::class.java;

        type.AllFields
                .filter { it.getAnnotation(Require::class.java) != null && it.name != signFieldName }
                .forEach {
                    var value = it.get(wxModel)
                    if (value is String && value.isNullOrEmpty()) {
                        return it.name;
                    }

                    if (value is Number && value.toInt() == 0) {
                        return it.name;
                    }
                }

        return "";
    }


    inline fun <reified T> sign(AppSecret: String, wxModel: T, signFieldName: String = "sign"): String {
        var msg = check(wxModel, signFieldName);
        if (msg.HasValue) {
            throw Exception("微信支付 ${msg} 字段不能为空")
        }

        var type = T::class.java;
        var list = type.declaredFields
                .map {
                    if (it.name == signFieldName) {
                        return@map "" to ""
                    }
                    var value = it.get(wxModel)
                    if (value is String && value.isNullOrEmpty()) {
                        return@map "" to ""
                    }

                    if (value is Number && value.toInt() == 0) {
                        return@map "" to ""
                    }

                    return@map it.name to value
                }
                .filter { it.first.isNotEmpty() }
                .sortedBy { it.first }
                .map { it.first + "=" + it.second }
                .toMutableList();

        list.add("key=${AppSecret}");
        return Md5Util.getMd5(list.joinToString("&")).toUpperCase();
    }
}